<template>
  <div class="app-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>知识库上传</span>
      </div>

      <!-- 文件上传区域 -->
      <el-form :model="uploadForm" label-width="120px">
        <el-form-item label="知识库标签">
          <el-input
            v-model="uploadForm.ragTag"
            placeholder="请输入知识库标签"
          ></el-input>
        </el-form-item>

        <el-form-item label="选择文件">
          <el-upload
            class="upload-demo"
            drag
            multiple
            action="/api/v1/rag/file/upload"
            :auto-upload="false"
            :on-change="handleFileChange"
            :on-remove="handleFileRemove"
            :on-error="handleUploadError"
            :before-upload="beforeUpload"
            :file-list="fileList"
            accept=".csv,.txt,.md,.xlsx,.xls,.doc,.docx"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">
              将文件拖到此处，或<em>点击上传</em>
            </div>
            <div class="el-upload__tip" slot="tip">
              <div>支持 CSV、TXT、MD、Excel、Word 等格式文件</div>
              <div class="upload-limits">
                <span>📁 单个文件最大：{{ fileSizeLimit }}MB</span>
                <span>⏱️ 上传超时：{{ uploadTimeout / 60000 }}分钟</span>
              </div>
              <div class="upload-tips">
                💡 大文件建议分批上传，网络不稳定时请耐心等待
              </div>
            </div>
          </el-upload>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="handleUpload" :loading="uploading">
            {{ uploading ? '上传中...' : '开始上传' }}
          </el-button>
          <span v-if="uploading" class="upload-status">
            <i class="el-icon-loading"></i>
            正在上传文件，请勿关闭页面...
          </span>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 知识库标签列表 -->
    <el-card class="box-card knowledge-list-card">
      <div slot="header" class="clearfix">
        <span class="card-title">已有知识库</span>
        <el-button
          style="float: right; padding: 3px 0"
          type="text"
          @click="refreshTagList"
          >刷新</el-button
        >
      </div>
      <div v-if="tagList.length === 0" class="empty-tags">
        <el-empty description="暂无知识库标签"></el-empty>
      </div>
      <div v-else class="tag-container">
        <div class="tag-header">
          <span class="tag-count">共 {{ tagList.length }} 个知识库</span>
        </div>
        <div class="tag-list">
          <el-tag
            v-for="tag in tagList"
            :key="tag"
            class="knowledge-tag"
            effect="plain"
            size="medium"
            type="primary"
          >
            <i class="el-icon-collection"></i>
            {{ tag }}
          </el-tag>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>
import { getRagTagList, uploadFile } from "@/api/rag";

export default {
  name: "KnowUpload",
  data() {
    return {
      uploadForm: {
        ragTag: "",
      },
      fileList: [],
      tagList: [],
      uploading: false,
      // 文件大小限制配置
      fileSizeLimit: 10, // MB
      // 超时时间配置
      uploadTimeout: 300000, // 5分钟
    };
  },
  created() {
    this.getTagList();
  },
  methods: {
    // 获取知识库列表
    async getTagList() {
      try {
        const res = await getRagTagList();
        if (res.code === "0000") {
          this.tagList = res.data;
        }
      } catch (error) {
        this.$message.error("获取知识库列表失败");
      }
    },
    // 刷新知识库
    refreshTagList() {
      this.getTagList();
    },
    // 文件改变时的钩子
    handleFileChange(file, fileList) {
      this.fileList = fileList;
    },
    // 移除文件时的钩子
    handleFileRemove(file, fileList) {
      this.fileList = fileList;
    },
    // 上传错误时的钩子
    handleUploadError(err, file, fileList) {
      this.$message.error("文件上传失败：" + (err.message || "未知错误"));
    },
    // 上传前的钩子
    beforeUpload(file) {
      // 检查文件类型
      const allowedTypes = ['.csv', '.txt', '.md', '.xlsx', '.xls', '.doc', '.docx'];
      const fileName = file.name.toLowerCase();
      const isValidType = allowedTypes.some(type => fileName.endsWith(type));
      
      if (!isValidType) {
        this.$message.error("只支持 CSV、TXT、MD、Excel、Word 格式的文件!");
        return false;
      }
      
      // 检查文件大小
      const fileSizeMB = file.size / 1024 / 1024;
      if (fileSizeMB > this.fileSizeLimit) {
        this.$message({
          message: `文件 "${file.name}" 过大！当前文件大小：${fileSizeMB.toFixed(2)}MB，最大支持：${this.fileSizeLimit}MB。建议将大文件拆分为多个小文件上传。`,
          type: 'warning',
          duration: 8000,
          showClose: true
        });
        return false;
      }
      
      // 检查文件大小是否过大（超过5MB给出警告）
      if (fileSizeMB > 5) {
        this.$message({
          message: `文件 "${file.name}" 较大（${fileSizeMB.toFixed(2)}MB），上传可能需要较长时间，请耐心等待。`,
          type: 'info',
          duration: 5000,
          showClose: true
        });
      }
      
      return true;
    },
    // 上传文件
    async handleUpload() {
      if (!this.uploadForm.ragTag) {
        this.$message.warning("请先输入知识库标签");
        return;
      }
      if (this.fileList.length === 0) {
        this.$message.warning("请选择要上传的文件");
        return;
      }

      // 计算总文件大小
      const totalSizeMB = this.fileList.reduce((total, file) => {
        return total + (file.raw ? file.raw.size / 1024 / 1024 : 0);
      }, 0);

      // 如果总文件大小超过限制，给出友好提示
      if (totalSizeMB > this.fileSizeLimit * 1.5) {
        this.$message({
          message: `总文件大小较大（${totalSizeMB.toFixed(2)}MB），建议分批上传以提高成功率。`,
          type: 'warning',
          duration: 6000,
          showClose: true
        });
      }

      this.uploading = true;
      
      // 创建超时控制器
      const timeoutId = setTimeout(() => {
        this.$message({
          message: "上传时间较长，请耐心等待，不要关闭页面...",
          type: 'info',
          duration: 0,
          showClose: true
        });
      }, 30000); // 30秒后提示

      try {
        const formData = new FormData();
        formData.append("ragTag", this.uploadForm.ragTag);
        this.fileList.forEach((file) => {
          formData.append("file", file.raw);
        });

        // 创建带超时的上传请求
        const uploadPromise = uploadFile(formData);
        const timeoutPromise = new Promise((_, reject) => {
          setTimeout(() => {
            reject(new Error('上传超时'));
          }, this.uploadTimeout);
        });

        const res = await Promise.race([uploadPromise, timeoutPromise]);

        clearTimeout(timeoutId);

        if (res && (res.code === "0000" || res.code === "200")) {
          this.$message.success("上传成功");
          this.getTagList();
          // 清空表单
          this.uploadForm.ragTag = "";
          this.fileList = [];
        } else {
          this.$message.error(res?.info || "上传失败，请稍后重试");
        }
      } catch (error) {
        clearTimeout(timeoutId);
        
        if (error.message === '上传超时') {
          this.$message({
            message: `上传超时！文件较大或网络较慢，建议：1. 检查网络连接 2. 将大文件拆分为小文件 3. 稍后重试`,
            type: 'error',
            duration: 10000,
            showClose: true
          });
        } else if (error.response) {
          // 请求已发出，但服务器响应的状态码不在 2xx 范围内
          const errorMsg = error.response.data?.info || "服务器响应错误";
          this.$message({
            message: `上传失败：${errorMsg}`,
            type: 'error',
            duration: 8000,
            showClose: true
          });
        } else if (error.request) {
          // 请求已发出，但没有收到响应
          this.$message({
            message: "网络连接异常，请检查网络后重试。如果问题持续存在，请联系管理员。",
            type: 'error',
            duration: 8000,
            showClose: true
          });
        } else {
          // 发送请求时出了点问题
          this.$message({
            message: `系统错误：${error.message || "未知错误"}，请联系管理员`,
            type: 'error',
            duration: 8000,
            showClose: true
          });
        }
      } finally {
        this.uploading = false;
      }
    },
  },
};
</script>

<style scoped>
.app-container {
  padding: 20px;
}
.box-card {
  margin-bottom: 20px;
  border-radius: 8px;
}
.knowledge-list-card {
  margin-top: 15px;
}
.card-title {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
}
.upload-demo {
  width: 100%;
}
.el-upload-dragger {
  width: 100%;
}
.tag-container {
  padding: 8px 0;
}
.tag-header {
  margin-bottom: 12px;
  color: #606266;
  font-size: 14px;
}
.tag-count {
  font-weight: 500;
}
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 0;
}
.knowledge-tag {
  padding: 6px 12px;
  border-radius: 6px;
  transition: all 0.3s ease;
  cursor: pointer;
  font-size: 13px;
  border: 1px solid #e4e7ed;
  background-color: #f5f7fa;
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.knowledge-tag:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  background-color: #ecf5ff;
  border-color: #409eff;
  color: #409eff;
}
.knowledge-tag i {
  margin-right: 4px;
  font-size: 14px;
  vertical-align: middle;
}
.empty-tags {
  padding: 20px 0;
}
.upload-limits {
  margin: 8px 0;
  display: flex;
  gap: 15px;
  flex-wrap: wrap;
}
.upload-limits span {
  font-size: 12px;
  color: #909399;
  background: #f5f7fa;
  padding: 2px 6px;
  border-radius: 4px;
}
.upload-tips {
  margin-top: 8px;
  font-size: 12px;
  color: #e6a23c;
  background: #fdf6ec;
  padding: 6px 8px;
  border-radius: 4px;
  border-left: 3px solid #e6a23c;
}
.upload-status {
  margin-left: 15px;
  color: #409eff;
  font-size: 14px;
  display: inline-flex;
  align-items: center;
}
.upload-status i {
  margin-right: 5px;
  animation: rotating 2s linear infinite;
}
@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>